// TestRtpRtcp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <thread>
#include <AfSocket.h>
#include "FileHelp.h"
#include "pcapParse.h"
int main0()
{
    // 输入rtp 流，输出264 

    CRtpManage tCRtpManage;
    int ret = tCRtpManage.init("");
    printf("init ret:%d \n", ret);

    ret = tCRtpManage.netPlay((const int8_t *) "", 58004, 0);

    printf("netPlay end \n");

    std::cout << "Hello World!\n";
	return 0;
}




int port = 8000;
// ipv6
#if 1
const char* server_ip = "fd00:192:168:60:b935:d615:1459:d4de";
const char* local_ip = "::";
#else
// ipv4
const char* server_ip = "127.0.0.1";
const char* local_ip = "0.0.0.0";
#endif

#define TCP 0
#define UDP 1

#define TCP_OR_UDP TCP


bool gStart = false;
bool gIsExit = false;


void thredFunTcp()
{
	ALTcpSocket tcpServer;

	//AfTcpSocket t_tcpClinetArray[100];

	std::list<ALTcpSocket> tListAfSocket;

	if (tcpServer.Listen(port, local_ip) < 0)
	{
		// 此端口不可用
		printf("failed to open socket on port: %d \n", port);
		return;
	}


	int timeout = 1000;
	timeval tm;
	tm.tv_sec = timeout / 1000;
	tm.tv_usec = timeout % 1000;
	std::vector<char> RecBuf;
	RecBuf.resize(1024 * 64);

	gStart = true;
	while (!gIsExit)
	{
		fd_set fds;
		FD_ZERO(&fds); // 清空集合
		FD_SET(tcpServer.hSock, &fds); // 加入集合

		int t_maxSocket = tcpServer.hSock;
		std::list<ALTcpSocket>::iterator it = tListAfSocket.begin();
		for (; it != tListAfSocket.end(); it++)
		{
			socket_t t_s = it->hSock;
			if (t_s > t_maxSocket)
			{
				t_maxSocket = t_s;
			}
			FD_SET(t_s, &fds);
		}

		int ret = select(t_maxSocket + 1, &fds, NULL, NULL, &tm);
		if (ret <= 0)
		{
			// 超时或被打断
			continue;
		}

		it = tListAfSocket.begin();
		for (; it != tListAfSocket.end(); it++)
		{
			bool isSet = FD_ISSET(it->hSock, &fds);
			if (isSet)
			{
				// 处理
				int ret = it->Recv(RecBuf.data(), 1024 * 64);
				printf("Recv ret:%d date[0]:%d \n", ret, RecBuf.data()[0]);

			}
		}
		if (FD_ISSET(tcpServer.hSock, &fds))
		{
			ALTcpSocket p;
			if (tcpServer.Accept(&p) < 0)
			{
				printf("server socket closing...\n"); // 关闭服务器
				break;
			}
			tListAfSocket.push_back(p);

			printf("########### new connect hSock:%d connects.size:%d \n", p.hSock, tListAfSocket.size());
		}

	}

	tcpServer.Close();
}



void thredFunUdp()
{
	ALUdpSocket udpServer;

	if (udpServer.bindUdpSock(port, local_ip) < 0)
	{
		// 此端口不可用
		printf("failed to udpServer socket on port: %d \n", port);
		return;
	}


	int timeout = 1000;
	timeval tm;
	tm.tv_sec = timeout / 1000;
	tm.tv_usec = timeout % 1000;
	std::vector<char> RecBuf;
	RecBuf.resize(1024 * 64);

	gStart = true;

	int nNum = 32;
	int maxBufLen = 1500;
	char* pBuffer[32];
	int nLen[32];
	uint16_t usPort[32];
	for (int i = 0; i < nNum; i++)
	{
		pBuffer[i] = new char[1500];
		nLen[i] = 0;
		usPort[i] = 0;
	}
	while (!gIsExit)
	{
		fd_set fds;
		FD_ZERO(&fds); // 清空集合
		FD_SET(udpServer.hSock, &fds); // 加入集合

		int t_maxSocket = udpServer.hSock;


		int ret = select(t_maxSocket + 1, &fds, NULL, NULL, &tm);
		if (ret <= 0)
		{
			// 超时或被打断
			continue;
		}


		bool isSet = FD_ISSET(udpServer.hSock, &fds);
		if (isSet)
		{
			// 处理
			ALSockAddr peer;

#ifdef WIN32
			int ret = udpServer.RecvFrom(RecBuf.data(), 1024 * 64, peer);
			printf("Recv ret:%d date[0]:%d ip:%s port:%d \n", ret, RecBuf.data()[0], peer.GetIp_str().c_str(), peer.GetPort());
#else

			std::vector<std::string>  ipVec;
			int ret = udpServer.MRecvFrom(pBuffer, nLen, ipVec, usPort, nNum, maxBufLen);

			for (int i = 0; i < ret; i++)
			{
				printf(" ret:%d [%d] ip:%s port:%d data[0]:%d len:%d \n", ret, i, ipVec[i].c_str(), usPort[i], pBuffer[i][0], nLen[i]);
			}
#endif
		}

	}

	udpServer.Close();
}

int main()
{

	// 读取wiresharke 提取出TCP 的rtp 的流，打印seq 和 ssrc 的值，如果seq 跳转则打印

	if (TCP_OR_UDP == TCP)
	{
		// 模拟服务器接收数据 start
		std::thread tThread(thredFunTcp);
		while (1)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
			if (gStart)
			{
				break;
			}
		}
		// 模拟服务器接收数据 end 

		ALTcpSocket tcpClient;


		int ret = tcpClient.Connect(server_ip, port);

		if (ret < 0)
		{
			printf("failed to connect to server !\n");
			return -1;
		}


		char* buf = new char[1024 * 128];

		uint16_t lastSeq = 0;
		int index = 0;
		while (1)
		{
			/*
			* uint16_t len = 100;
			int ret = 0;

			buf[0] = index % 127;
			index++;

			{
				int sendRet = tcpClient.Send(buf, len);
				printf("sendRet:%d len:%d \n", sendRet, len);
			}
			*/
			
			//printf("######### ret:%d seq:%d ssrc:%x\n", ret,header.sequenceNumber, header.ssrc);

			uint16_t len = 0;
			int ret = 0;

			ret = ReadFile::GetInstans().RFile((char*)"diubao003-dst42000.bin", (char*)&buf[0], 2);

			uint16_t* p = (uint16_t*)buf;
			len = *p;
			len = swap16(len);
			if (ret <= 0)
			{
				break;
			}
			ret = ReadFile::GetInstans().RFile((char*)"diubao003-dst42000.bin", (char*)&buf[2], len);
			if (ret <= 0)
			{
				break;
			}
			RTPHeader header;
			bool ok = rtpParse(header, (const void*)&buf[2], len);

			//if (header.sequenceNumber - lastSeq != 1)
			{
				printf("#########  ***** seqNum:%d lastSeq:%d lossNum:%d ssrc:%x %d\n", header.sequenceNumber, lastSeq, header.sequenceNumber - lastSeq, header.ssrc, header.ssrc);

			}
			lastSeq = header.sequenceNumber;

			{
				int sendRet = tcpClient.Send(buf, len + 2);
				printf("sendRet:%d len:%d \n", sendRet, len + 2);
			}
			//printf("######### ret:%d seq:%d ssrc:%x\n", ret,header.sequenceNumber, header.ssrc);


		}

		gIsExit = true;
		tThread.join();
		return 0;
	}
	if (TCP_OR_UDP == UDP)
	{
		// 模拟服务器接收数据 start
		std::thread tThread(thredFunUdp);
		while (1)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(1));
			if (gStart)
			{
				break;
			}
		}
		// 模拟服务器接收数据 end 

		ALUdpSocket udpClient;

		udpClient.bindUdpSock(5800, local_ip);


		char* buf = new char[1024 * 128];

		uint16_t lastSeq = 0;
		int index = 0;

		int nNum = 32;
		int maxBufLen = 1500;
		char* pBuffer[32];
		int nLen[32];
		uint16_t usPort[32];
		for (int i = 0; i < nNum; i++)
		{
			pBuffer[i] = new char[1500];
			nLen[i] = 0;
			usPort[i] = 0;
		}


		while (1)
		{
			uint16_t len = 100;
			int ret = 0;
			{
				ALSockAddr afAddr(server_ip, port);
				buf[0] = index % 127;
				for (int i = 0; i < nNum; i++)
				{
					pBuffer[i][0] = index % 127;
					nLen[i] = 1500;
				}
				index++;
#ifdef WIN32
				int sendRet = udpClient.SendTo(buf, len, afAddr);
#else

				int sendRet = udpClient.MSendto(pBuffer, nLen, nNum, afAddr);
#endif

				printf("sendRet:%d len:%d \n", sendRet, len);
			}
			//printf("######### ret:%d seq:%d ssrc:%x\n", ret,header.sequenceNumber, header.ssrc);
			std::this_thread::sleep_for(std::chrono::milliseconds(10));

		}

		gIsExit = true;
		tThread.join();
		return 0;


	}

	std::cout << "Hello World!\n";
	return 0;
}
